package performance

import (
	"mi/internal/system"
)

var enabled = false
var profilerStart int64 = 0
var counts = make(map[string]int64)
var marks = make(map[string]int64)
var measures = make(map[string]int64)


// Marks a performance event.
// param markName The name of the mark.
func Mark(markName string) {
	if enabled {
		marks[markName] = system.CurrentMillisecond()
		counts[markName] = counts[markName] + 1
	}
}

// Adds a performance measurement with the specified name.
//
// param measureName The name of the performance measurement.
// param startMarkName The name of the starting mark. If not supplied, the point at which the
// 			profiler was enabled is used.
// param endMarkName The name of the ending mark. If not supplied, the current timestamp is used.
func Measure(measureName string, markName ... string) {
	if enabled {
		var start int64
		var end int64
		if len(markName) >= 2 {
			end = marks[markName[1]]
		} else {
			end = system.CurrentMillisecond()
		}

		if len(markName) >= 1 {
			start = marks[markName[0]]
		} else {
			start = profilerStart
		}

		measures[measureName] = measures[measureName] + (end - start)
	}
}

// Gets the number of times a marker was encountered.
//
// param markName The name of the mark.
func GetCount(markName string) int64 {
	return counts[markName]
}

// Gets the total duration of all measurements with the supplied name.
//
// param measureName The name of the measure whose durations should be accumulated.
func GetDuration(measureName string) int64 {
	return measures[measureName]
}

// Iterate over each measure, performing some action
//
// param cb The action to perform for each measure
func ForEachMeasure(cb func (measureName string, duration int64)) {
	for key, measure := range measures {
		cb(key, measure)
	}
}

// Enables (and resets) performance measurements for the compiler.
func Enable() {
	enabled = true
	profilerStart = system.CurrentMillisecond()
	counts = make(map[string]int64)
	marks = make(map[string]int64)
	measures = make(map[string]int64)
}

// Disables performance measurements for the compiler.
func Disable() {
	enabled = false
}